﻿using ServerCommon.Log;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;

namespace ServerCommon.Net
{
    public class ServerSettings
    {
        private static readonly LogHelper log = LogHelper.GetLogger(typeof(ServerSettings));

        /// <summary>
        /// 最大连接数
        /// </summary>
        public int MaxConnections { get; private set; }

        /// <summary>
        /// 执行 send/recv 操作的socketAsyncEvent的数量
        /// </summary>
        public int IOSAEANum { get; private set; }

        /// <summary>
        /// 执行 accept 操作的socketAsyncEventArgs的数量
        /// </summary>
        public int AcceptSAEANum { get; private set; }

        /// <summary>
        /// 挂起连接的最大长度
        /// </summary>
        public int BackLog { get; private set; }

        /// <summary>
        /// socketAsyncEventArgs的Buffer长度
        /// </summary>
        public int BufferSizeForEachBlock { get; private set; }

        /// <summary>
        /// 服务器监听的端口设置
        /// </summary>
        public IPEndPoint LocalEndPoint { get; private set; }

        /// </summary>
        /// <param name="maxConnections">最大连接数，同时连入服务的客户端个数</param>
        /// <param name="sendSAEANum">最大同时执行发送操作的连接的个数（</param>
        /// <param name="acceptSAEANum">同时执行accept操作的链接的个数</param>
        /// <param name="backLog"></param>
        /// <param name="bufferSizeForEachBlock">每个SAEA分配的缓存</param>
        /// <param name="ip">监听的IP</param>
        /// <param name="port">监听的端口号</param>
        /// <summary>
        public ServerSettings(int maxConnections, int acceptSAEANum, int backLog, int bufferSizeForEachBlock, string ip, int port)
        {
            MaxConnections = maxConnections;
            IOSAEANum = maxConnections * 2;
            AcceptSAEANum = acceptSAEANum;
            BackLog = backLog;
            BufferSizeForEachBlock = bufferSizeForEachBlock;

            var ipAddresses = Dns.GetHostAddresses(ip);
            IPAddress ipAddress = IPAddress.None;
            foreach (var address in ipAddresses)
            {
                if (address.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork || ipAddress == IPAddress.None)
                {
                    log.InfoFormat("use IPAddress : {0}", address);
                    ipAddress = address;
                }
                log.InfoFormat("ip: {0} address: {1}", ip, address);
            }
            if (ipAddresses.Length <= 0 || ipAddress == IPAddress.None)
            {
                log.ErrorFormat("can't get ipaddress by ip: {0} or ipAddress not contain ipv4.", ip);
            }

            LocalEndPoint = new IPEndPoint(ipAddresses[0], port);
        }

        public ServerSettings(string ip, int port, int maxConnection, int blockSize)
        {
            MaxConnections = maxConnection;
            IOSAEANum = maxConnection * 2;
            AcceptSAEANum = 1000;
            BackLog = 100;
            BufferSizeForEachBlock = blockSize;

            IPAddress ipAddress = IPAddress.None;
            if (ip == "0.0.0.0")
            {
                ipAddress = IPAddress.Parse(ip);
                log.InfoFormat("ServerSettings: ip 0.0.0.0");
            }
            else
            {
                var ipAddresses = Dns.GetHostAddresses(ip);
                foreach (var address in ipAddresses)
                {
                    if (address.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork || ipAddress == IPAddress.None)
                    {
                        log.InfoFormat("use IPAddress : {0}", address);
                        ipAddress = address;
                    }
                    log.InfoFormat("ip: {0} address: {1}", ip, address);
                }
                if (ipAddresses.Length <= 0 || ipAddress == IPAddress.None)
                {
                    log.ErrorFormat("can't get ipaddress by ip: {0} or ipAddress not contain ipv4.", ip);
                }
            }

            LocalEndPoint = new IPEndPoint(ipAddress, port);
        }
    }
}
